local Widget = require "widgets/widget"
local Text = require "widgets/text"
local Image = require "widgets/image"

local function tkr()
    return Image('images/global.xml','square.tex')
end

local function tint(r,g,b,a)
    if a then
        return r/255,g/255,b/255,a
    end
    return r/255,g/255,b/255
end

local sort_order = {
    'lv',
    'exp',
    'drain',
    'cc',
    'cd',
}

local map = {
    lv = {
        name = '等级:'
    },
    exp = {
        name = '经验值:',
        unique = true,
    },
    drain = {
        name = '吸血:'
    },
    cc = {
        name = '暴击率:'
    },
    cd = {
        name = '暴击伤害:'
    },
}

---@class bh_mobius_lvlup_info
---@field left widget_text
---@field right any

---@class widget_bh_mobius_lvlup : widget_widget
---@field root widget_image
---@field frame widget_image
---@field frame_inner widget_image
---@field body widget_image
---@field info table<string,bh_mobius_lvlup_info>
local bh_mobius_lvlup = Class(Widget, 
---comment
---@param self widget_bh_mobius_lvlup
function(self)
    Widget._ctor(self, 'bh_mobius_lvlup') -- 调用基类构造函数

    local w,h = 450,250
    self.root = self:AddChild(tkr())
    self.root:SetVAnchor(ANCHOR_MIDDLE)
    self.root:SetHAnchor(ANCHOR_MIDDLE)
    self.root:SetPosition(0,280)
    self.root:SetSize(w,h)
    self.root:SetTint(tint(0,0,0,1))

    local outline_width = 1
    self.frame = self.root:AddChild(tkr())
    self.frame:SetTint(tint(255,222,15,1))
    self.frame:SetSize(w-outline_width*2,h-outline_width*2)

    local frame_width = 2
    self.frame_inner = self.root:AddChild(tkr())
    self.frame_inner:SetTint(tint(0,0,0,1))
    self.frame_inner:SetSize(w-frame_width*2-outline_width*2,h-frame_width*2-outline_width*2)

    self.body = self.root:AddChild(tkr())
    self.body:SetTint(tint(48,48,48,1))
    self.body:SetSize(w-frame_width*2-outline_width*2-outline_width*2,h-frame_width*2-outline_width*2-outline_width*2)


    self.info = {}


    local info_left_max_len = 8
    local font_size_w,font_size_h = 20,20
    local font_size = font_size_h * 1.3
    local x_padding,y_padding = 5,15
    local line_spacing = 5

    local exp_bar_lenth = 250
    local exp_bar_gap = 2
    local exp_bar_offset = 2

    self.exp_bar_real_width_max = exp_bar_lenth - exp_bar_gap * 2
    self.exp_bar_real_h_max = font_size_h - exp_bar_gap * 2

    for i,v in ipairs(sort_order) do
        self.info[v] = {}
        self.info[v].left = self.body:AddChild(Text(BODYTEXTFONT, font_size))
        self.info[v].left:SetRegionSize(font_size_w*info_left_max_len,font_size_h)
        self.info[v].left:SetVAlign(ANCHOR_MIDDLE)
        self.info[v].left:SetHAlign(ANCHOR_LEFT)
        self.info[v].left:SetString(map[v].name)
        self.info[v].left:SetPosition(-w/2+outline_width*2+frame_width+x_padding+(font_size_w*info_left_max_len)/2,h/2-outline_width*2-frame_width-y_padding-(font_size_h+line_spacing)*(i-1))

        if not map[v].unique then
            self.info[v].right = self.body:AddChild(Text(BODYTEXTFONT, font_size))
            self.info[v].right:SetRegionSize(100,font_size_h)
            self.info[v].right:SetVAlign(ANCHOR_MIDDLE)
            self.info[v].right:SetHAlign(ANCHOR_LEFT)
            self.info[v].right:SetString('0')
            self.info[v].right:SetPosition(-w/2+outline_width*2+frame_width+x_padding+(font_size_w*info_left_max_len)/2+font_size_w*2,h/2-outline_width*2-frame_width-y_padding-(font_size_h+line_spacing)*(i-1))
        end
        if v == 'exp' then
            ---@type widget_image
            self.info[v].right = self.body:AddChild(tkr())
            self.info[v].right:SetTint(tint(0,0,0,1))
            self.info[v].right:SetSize(exp_bar_lenth,font_size_h)
            self.info[v].right:SetHRegPoint(ANCHOR_LEFT)
            self.info[v].right:SetPosition(-w/2+outline_width*2+frame_width+x_padding+(font_size_w*info_left_max_len)/2+font_size_w*2,h/2-outline_width*2-frame_width-y_padding-(font_size_h+line_spacing)*(i-1))

            self.info[v].right_bar = self.info[v].right:AddChild(tkr())
            self.info[v].right_bar:SetTint(tint(40,255,255,1))
            self.info[v].right_bar:SetSize(0,self.exp_bar_real_h_max)
            self.info[v].right_bar:SetHRegPoint(ANCHOR_LEFT)
            self.info[v].right_bar:SetPosition(exp_bar_offset,0)

            self.info[v].right_bar_text = self.info[v].right:AddChild(Text(BODYTEXTFONT, font_size))
            self.info[v].right_bar_text:SetRegionSize(exp_bar_lenth,font_size_h)
            self.info[v].right_bar_text:SetString('0/0')
            self.info[v].right_bar_text:SetPosition(exp_bar_offset+self.exp_bar_real_width_max/2,0)
        end
    end

    ThePlayer:ListenForEvent('bh_mobius_lv_exp_onchange',function ()
        self:DoUpdate()
    end)

end)


function bh_mobius_lvlup:DoUpdate()
    if ThePlayer and ThePlayer.replica.bh_mobius_lv then
        local lv = ThePlayer.replica.bh_mobius_lv:GetVal() or 0
        local exp = ThePlayer.replica.bh_mobius_lv:GetEXP()
        local exp_bar_max = math.floor(math.log(lv+1)*2000+1000)
        local exp_bar_width = exp/exp_bar_max * self.exp_bar_real_width_max
        self.info.exp.right_bar:SetSize(exp_bar_width,self.exp_bar_real_h_max)

        self.info.exp.right_bar_text:SetString(S_BH_MOBIUS:fnum(2,exp)..'/'..S_BH_MOBIUS:fnum(0,exp_bar_max))

        self.info.lv.right:SetString(tostring(lv))
        local drain = S_BH_MOBIUS:fnum(2,lv*.01)
        self.info.drain.right:SetString(tostring(drain))
        local cc = 0.5*lv
        self.info.cc.right:SetString(tostring(cc))
        local cd = 1+lv*.1
        self.info.cd.right:SetString(tostring(cd))
    end
end

return bh_mobius_lvlup